package com.cskaoyan.javase.oop3._2inner._1member._1basic;

/**
 * 在具体探究访问的特点之前,先明确以下两个大前提:
 *      1.内部类和外围类是"好兄弟"，它们之间的访问不受访问权限限制，包括私有。
 *      2.成员内部类对象依赖于外围类对象而存在,成员内部类对象会持有外围类对象的引用作为自身成员变量.
 *          思考以下问题:
 *          a.成员内部类的成员方法中,存在几个对象呢? 存在2个对象
 *          肯定存在this指向当前自身对象,其次还存在外围类的对象
 *          这两个对象:
 *              用this关键字指向自身成员内部类对象
 *              用"外围类类名.this"指向外围类对象
 *
 *          b.成员内部类的静态成员方法中,存在几个对象呢? (成员内部类没有静态方法)
 *          c.外围类的成员方法中有几个对象?
 *              只有一个,this指向自身外围类对象
 *              切记,没有成员内部类对象
 *          d.外围类的静态成员方法中有几个对象?
 *              没有,一个都没有
 *
 * 成员内部类的访问特点,主要从以下几个角度研究：
 *      1.成员内部类当中去访问外围类成员(重点)
 *          首先访问是在成员内部类的成员方法中去访问
 *          由于已经存在外围类对象了,所以可以直接访问外围类成员
 *          并且访问不受权限限制.
 *          如果出现外围类成员和成员内部类成员名字一样的情况
 *          那就用:
 *          "外围类类名.this"指向外围类对象来区分
 *          "this"指向自身对象
 *
 *      2.外围类去访问成员内部类成员(重点)
 *       访问的位置要分两种:
 *          a.成员方法,隐含this指向自身对象,没有内部类对象.
 *          在这里想要访问内部类成员,咋办?
 *          需要创建成员内部类对象
 *          怎么创建?
 *          成员内部类对象需要依赖于外围类对象而存在
 *          所以创建成员内部类对象,需要在外围类对象的基础上创建
 *          既然外围类对象已经存在了
 *          所以可以"直接创建成员内部类对象"
 *
 *          b.静态方法,啥对象都没有
 *           需要创建成员内部类对象
 *           首先需要创建外围类对象
 *           在外围类对象的基础上创建成员内部类对象
 *
 *      3.外部类去访问成员内部类成员(了解)
 *          需要创建成员内部类对象
 *          但是这个过程,首先需要外围类的权限,其次需要成员内部类的权限
 *          最后在访问成员内部类成员时,也需要考虑权限
 *
 *      4.成员内部类访问外部类成员(了解)
 *          正常创建对象访问
 *          全程都受权限限制
 *
 *
 *
 * @since 16:27
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // 在其他类中创建成员内部类对象
        EnclosedClazz.InnerClazz ic = new EnclosedClazz().new InnerClazz();
        System.out.println(ic.a);
        // ic.b
    }
}

// 外围类
class EnclosedClazz {
    int a = 10;
    private int b = 20;
    static int c = 30;
    static final int D = 40;

    public void test() {
        // 直接创建成员内部类对象
        InnerClazz ic = new InnerClazz();
        System.out.println(ic.a);
        System.out.println(ic.b);

        // 何为在外围类对象的基础上创建成员内部类对象?
        InnerClazz ic2 = this.new InnerClazz();
    }

    public static void testStatic(){
        EnclosedClazz ec = new EnclosedClazz();
        InnerClazz ic = ec.new InnerClazz();
        System.out.println(ic.b);
        // 上述代码,链式调用二合一
        InnerClazz ic2 = new EnclosedClazz().new InnerClazz();
    }

    // 成员内部类
    class InnerClazz {
        int a = 100;
        private int b = 200;
        static final int D = 400;

        // 成员方法
        public void testInner() {
            System.out.println(a);
            System.out.println(b);
            System.out.println(EnclosedClazz.this.a);
            System.out.println(EnclosedClazz.this.b);
            System.out.println(EnclosedClazz.c);
            System.out.println(EnclosedClazz.D);
        }

        public void testInner2(int a) {
            System.out.println(a);
            System.out.println(this.a);
            System.out.println(EnclosedClazz.this.a);
        }
    }
}
